So now we have a GUI that is redrawing itself 10 times per second, or so, and the GUI reflects the underlying data model. The next step is to see that the data model is being altered regularly. If the model changes over time, its visual representation should corresondingly change over time, resulting in animation. To do that we create at least one thread that regularly alters the data model. In my example I call this a Worker object. If you look at the Worker code you will see that it contains no GUI code. All it does is change the data in the model. The animation comes from the GUI timer regularly firing so as to trigger a redraw of the panel. When the panel it draws a representation of the underlying model. If the model has changed (been changed by the Worker(s)) the frame of animation will differ from the previous one. In aggregate all these renderings will yield an animation.
The following code provides an example. When run, the program shows a small red square moving somewhat randomly diagonally from the upper-left corener to the lower-right. The program consists of a driver (DemoMultiThreadedAnimation) that creates the underlying data model object (a DataModel instance), a GUI consisting of a Frame and Panel that are bound to the DataModel object, and two Workers (each a Thread) that are also bound to the DataModel object. One of the Workers moves the red square to the right, and the other moves the square downward. The DataModel object serves as the intermediary between the two Worker threads and the GUI thread (in Java, this is the "Swing" thread). The threads run concurrently: the Workers change the DataModel intermittently. The GUI thread, prompted by the Timer, renders the GUI to reflect the DataModel regularly (every 10th to 20th of a second). The program terminates after the position of the square is changed (by the Workers) 100 times.